﻿#include "ssNode.h"


namespace StarSeeker
{

ssNode::ssNode()
:ssObject("Object")
{
	m_pParent = 0;
	memset(m_components, 0, sizeof(m_components));
	m_transform.m_pNode = this;
	m_components[0] = &m_transform;
}

ssNode::ssNode(const char* name)
:ssObject(name)
{
	m_pParent = 0;
	memset(m_components, 0, sizeof(m_components));
	m_transform.m_pNode = this;
	m_components[0] = &m_transform;
}

ssNode::~ssNode()
{
	//删除子节点
	DelAllChild();
	//删除元素
	DelAllComponents();
	m_pParent = 0;
}

ssError ssNode::AddChild(ssNode* pNode)
{
	m_children.PushBack(pNode);
	pNode->m_pParent = this;
	return SS_OK;
}

ssError ssNode::DelChild(ssNode* pNode)
{
	if (pNode)
	{
		ssList<ssNode*>::Iterator itr = m_children.Begin();
		while (itr.IsVaild())
		{
			if (*itr == pNode)
			{
				delete *itr;
				m_children.EraseItr(itr);
				return SS_OK;
			}
			++itr;
		}
	}
	return SS_CHILED_NOT_FOUND;
}

ssError ssNode::DelChild(const char* name)
{
	if (name)
	{
		ssList<ssNode*>::Iterator itr = m_children.Begin();
		while (itr.IsVaild())
		{
			if ((*itr)->NameIs(name))
			{
				delete *itr;
				m_children.EraseItr(itr);
				return SS_OK;
			}
			++itr;
		}
	}
	return SS_CHILED_NOT_FOUND;
}

void ssNode::DelAllChild()
{
	ssList<ssNode*>::Iterator itr = m_children.Begin();
	while (itr.IsVaild())
	{
		delete *itr;
		++itr;
	}
	m_children.Empty();
}

ssError ssNode::RemoveChild(ssNode* pNode)
{
	if (pNode)
	{
		ssList<ssNode*>::Iterator itr = m_children.Begin();
		while (itr.IsVaild())
		{
			if (*itr == pNode)
			{
				m_children.EraseItr(itr);
				return SS_OK;
			}
			++itr;
		}
	}
	return SS_CHILED_NOT_FOUND;
}

ssComponent* ssNode::GetComponent(u32 type)
{
	if (type < ssComponent::SS_COMPONENT_MAX)
	{
		return m_components[type];
	}
	return 0;
}

ssNode* ssNode::FindChild( const char* name )
{
	ssList<ssNode*>::Iterator itr = m_children.Begin();
	while (itr.IsVaild())
	{
		if ((*itr)->NameIs(name))
		{
			return *itr;
		}
		++itr;
	}
	return 0;
}

ssNode* ssNode::FindChild(u32 offset)
{
	u32 num = 0;
	ssList<ssNode*>::Iterator itr = m_children.Begin();
	while (itr.IsVaild())
	{
		if (offset == num++)
		{
			return *itr;
		}
		itr;
	}
	return 0;
}

ssList<ssNode*>& ssNode::GetChildren()
{
	return m_children;
}

ssNode* ssNode::Parent()
{
	return m_pParent;
}

void ssNode::SetParent(ssNode* pNode)
{
	if (m_pParent)
	{
		m_pParent->RemoveChild(this);
	}
	m_pParent = pNode;
	if (pNode)
	{
		m_transform.UpdateGlobalMatrix();
	}
}

ssError ssNode::AddComponent(ssComponent* pComponent)
{
	if (pComponent && pComponent->m_type<ssComponent::SS_COMPONENT_MAX)
	{
		ssComponent* old = GetComponent(pComponent->GetType());
		if (old)
		{
			return SS_SOLE_ELEMENT_EXISTED;
		}
		else
		{
			pComponent->m_pNode = this;
			m_components[pComponent->GetType()] = pComponent;
			pComponent->OnAdd();
			return SS_OK;
		}
	}
	return SS_ERROR;
}

ssError ssNode::ReplacComponent(ssComponent* pComponent)
{
	if (pComponent && pComponent->GetType()>ssComponent::SS_COMPONENT_TRANSFORM && pComponent->GetType()<ssComponent::SS_COMPONENT_MAX)
	{
		ssComponent* old = GetComponent(pComponent->GetType());
		if (old)
		{
			delete old;
		}
		pComponent->m_pNode = this;
		m_components[pComponent->GetType()] = pComponent;
		pComponent->OnAdd();
		return SS_OK;
	}
	return SS_ERROR;
}

bool ssNode::DelComponent(ssComponent* pComponent)
{
	if (pComponent)
	{
		return DelComponent(pComponent->GetType());
	}
	return false;
}

bool ssNode::DelComponent( u32 type )
{
	if (type > ssComponent::SS_COMPONENT_TRANSFORM && type < ssComponent::SS_COMPONENT_MAX)
	{
		if (m_components[type])
		{
			delete m_components[type];
		}
		m_components[type] = 0;
		return true;
	}
	return false;
}

void ssNode::DelAllComponents()
{
	for (u32 i = 1; i < ssComponent::SS_COMPONENT_MAX; ++i)
	{
		if (m_components[i])
		{
			delete m_components[i];
		}
		m_components[i] = 0;
	}
}

void ssNode::Reset()
{
	DelAllChild();
	DelAllComponents();
	SetName("Object");
	m_pParent = 0;
}

ssTransform& ssNode::Transform()
{
	return m_transform;
}

}
